package com.cy.pet.zuul.config;

import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;

import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * 资源服务器的配置，在这个对象中重点要实现：
 * 1）JWT令牌解析的配置(客户端带着令牌访问资源时，要对令牌进行解析)
 * 2）启动资源访问的授权配置(不是所有登录用户可以访问所有资源)
 */
@Configuration
@EnableResourceServer //此注解会启动资源服务器的默认配置
@EnableGlobalMethodSecurity(prePostEnabled = true) //执行方法之前启动权限检查
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Autowired
    private TokenStore tokenStore;

    /**
     * token服务配置
     * @param resources
     * @throws Exception
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(tokenStore);
    }

    /**
     * 路由安全认证配置
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        //1.关闭跨域攻击
        http.csrf().disable();
        //3.处理异常(授权异常)403
        /*http.exceptionHandling()
                .accessDeniedHandler(accessDeniedHandler());
        //4.处理异常(认证异常)401
        http.exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint());*/
//        http.exceptionHandling().accessDeniedHandler(accessDeniedHandler());
        //2.放行所有资源(对资源的访问不做认证)
        http.authorizeRequests().anyRequest().permitAll();
    }
    public AuthenticationEntryPoint authenticationEntryPoint(){
        return (request,response,exception)->{
            Map<String,Object> map = new HashMap<>();
            map.put("state", HttpServletResponse.SC_UNAUTHORIZED);
            map.put("message","您没有认证，请先登录");
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/json;charset=utf-8");
            PrintWriter out = response.getWriter();
            String result = new ObjectMapper().writeValueAsString(map);
            out.println(result);
            out.flush();
        };
    }
    @Bean
    public AccessDeniedHandler accessDeniedHandler(){
        return (request, response, exception) -> {
            Map<String,Object> map = new HashMap<>();
            map.put("state", HttpServletResponse.SC_FORBIDDEN);
            map.put("message","您没有访问权限，请联系管理员");
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/json;charset=utf-8");
            PrintWriter out = response.getWriter();
            String result = new ObjectMapper().writeValueAsString(map);
            out.println(result);
            out.flush();
        };
    }
}
